# -*- coding: utf-8 -*-

from ConfigParser import ConfigParser, NoOptionError
from film import FilmDescriptor
from gtkmvc import Model
from hachoir_core.cmd_line import unicodeFilename
from hachoir_core.i18n import _, getTerminalCharset
from hachoir_core.tools import makePrintable
from hachoir_metadata import extractMetadata
from hachoir_parser import createParser
from utils import convertMedataListToDict
import os
import sys
import string
import shutil

class PyvrModel (Model):
    """Our model contains a numeric counter and a numeric value that
    holds the value that the counter must be assigned to when we the
    model is reset"""

    __properties__ = {
        'directory' : '.',
        'file' : None,
        'new_filename' : None,
        'film' : FilmDescriptor,
        'quality' : None,
        'mask_length' : 0, # nombre de caractère du nom de fichier original à garder
        'vcodec' : None,
        'acodec' : None,
        'nfo' : '' # force nfo value change
        }

    lang = {}
    config = None
    nfo_create = None
    destination_directory = None

    def __init__(self):
        Model.__init__(self)
       
        # load config object
        # run package default configuration and overload with user settings
        self.config = ConfigParser()
        self.config.read([
                          os.path.join(sys.path[0], 'pyvr.ini'),
                          os.path.expanduser(os.path.join('~', '.pyvr.ini')),
                          ])
        
        self.directory = self.config.get('general', 'files_path')
        self.destination_directory = self.config.get('general', 'destination_path')
        return


    def save(self):
        """ 
        effectue le deplacement du film et du nfo si trouve
        le nfo est automaitquement créé si demandé 
        """

        """ le film """
        src = os.path.join(self.directory, self.file)
        dst = os.path.join(self.destination_directory, self.new_filename)
        shutil.move(src, dst)



        """ on cree le nom du nouvel nfo """
        t = self.new_filename.rsplit('.', 1)
        new_nfo = "%s.nfo" % t[0]
        nfo_dir = os.path.join(self.destination_directory, self._get_config('general', 'nfo_dir'))
        nfo_dst = os.path.join(nfo_dir, new_nfo)

        ## si le repertoire nfo de destination n'existe pas on le cré
        if(not os.path.exists(nfo_dir)):
            os.mkdir(nfo_dir)

        if(self.nfo):
            shutil.move(self.nfo, nfo_dst)
            
        if (self.nfo_create):
            nfo = open(nfo_dst, 'w')
            nfo.write('create from py-video-renamer (maybe allocine number could be added...)')
            nfo.close()
                
        return
    
    def get_file_list(self):
        """ retourne la listes des fichiers videos du repertoire sélectionné """
    
        d = self.directory
        
        extensions = self.config.get('general', 'file_extensions').split(',')
        files = os.listdir(d) ## liste les fichiers du repertoire
        
        t_files = []
        for file in files:
          pathname = os.path.join(d, file)
          if os.path.isfile(pathname):
              t = file.rsplit('.', 1) ## path+fichier , extension
                   
              if len(t) < 2 : continue ## skip if no extension found ...   
                 
              if extensions.count(t[1]): ## filter only video extension
                  t_files.append(file)
          
        t_files.sort()      
        return t_files
 
    def find_nfo(self, filename):
        """ cherche un fichier nfo associé  dans le repertoire courant 
        puis dans le repertoire specifié dans le fichier de config
        
        le model est mis a jour avec le chemin complet vers le fichier nfo trouvé
        """
        
        ## build nfo file name
        t = filename.rsplit('.', 1)
        nfo_file = "%s.nfo" % t[0]
        
        nfo_dir = self._get_config('general', 'nfo_dir')
        local_nfo = os.path.join(self.directory , nfo_file)
        other_nfo = os.path.join(self.directory, nfo_dir , nfo_file)
        for nfo in [local_nfo, other_nfo]:
            if (os.path.exists(nfo)):
                self.nfo = nfo
                return
        self.nfo = None
        return
 
    def set_nfo_create(self, bool):
        """ active | desactive la création de nfo """
        self.nfo_create = bool
        return
 
    def get_lang(self):
        return self._get_config('general', 'lang', True)
    
    def get_quality_list(self):
        return self._get_list_from_config('general', 'video_quality')

    def get_video_codec_list(self):
        return self._get_list_from_config('general', 'video_codecs')

    def get_audio_codec_list(self):
        return self._get_list_from_config('general', 'audio_codecs')

    def _get_list_from_config(self, section, key):
        t = self._get_config(section, key, True)
        t.insert(0, self._get_config('general', 'label_unknow'))
        return t


    def lang_toggle(self, lang, type, toggle):
        self.lang[lang] = self.lang.get(lang, {})
        self.lang[lang][type] = self.lang[lang].get(type, -1)
        self.lang[lang][type] = toggle
        return

    def update_new_filename(self):
        """ propose un nouveau nom de fichier """
        
        if(self.file == None): return
        
        s_spec = ''

        # langues
        if(len(self.lang)):
            # audio
            t_lang = []
            for i in self.lang.keys():
                if self.lang.get(i, False) and self.lang[i].get('audio', 0):
                    t_lang.append(i)
            s_lang = ('+').join(t_lang)

            # sub
            for lang in self.lang.keys():
                if(self.lang.get(lang, False) and self.lang[lang].get('sub', 0)):
                    s_lang += self._get_config('general', 'subtitle_keyword', False)
                    break

            s_spec += s_lang

        
        if(self.quality and self._has_meaning(self.quality)):
            s_spec += '.'+self.quality

        if(self.vcodec and self._has_meaning(self.vcodec)):
            s_spec += '.'+self.vcodec

        if(self.acodec and self._has_meaning(self.acodec) and self.acodec != 'MP3'):
            s_spec += '-'+self.acodec
        
        # split around extension
        t_file = self.file.rsplit('.', 1)
        
        title = self._clean_file_name(t_file[0]) # nettoyage du nom du fichier
        title = title[0:self.mask_length] # application du masque
        title = string.capwords(title).replace(' ', '.') # pas d'espace
        
        title += '-' + s_spec
        
        self.new_filename = '%s.%s' % (title, t_file[1])
        return


    def _has_meaning(self, value):
        return value != self._get_config('general', 'label_unknow')

    def _get_config(self, section, key, split=False):
        ret = self.config.get(section, key)
        if split: ret = ret.split(',')

        return ret
    
    def analyse_film(self):
        """ move in other place ??? """
        
        filename = unicodeFilename(os.path.join(self.directory, self.file))
        parser = createParser(filename)

        if not parser:
            print >>stderr, "Unable to parse file"
            exit(1)
        try:
            metadata = extractMetadata(parser)
        except HachoirError, err:
            print "Metadata extraction error: %s" % unicode(err)
            metadata = None
        if not metadata:
            print "Unable to extract metadata"
            exit(1)
        
        
        metadataList = metadata.exportPlaintext(None, False) ## extract mode non humain
        metadataDict = convertMedataListToDict(metadataList)

        film = FilmDescriptor(self.file)
        
        group = None
        for item in metadataDict: # boucle sur les groupes

            for type in film.get_methods():
                if item.count(type):
                    
                    #print "processing group %s (type=%s)" % (item, type) 
                    getattr(film, 'add_'+type)(metadataDict[item])
        
        self.film = film
        return

    def _clean_file_name(self, title):
        """ retourne le nom du fichier en netoyant un maximum de chaines connus (codec,langues,team,etc...)"""
    
        title = title.lower()
        
        # nettoyage des mots clefs
        for pattern in self._get_config('general', 'patterns_to_exlude', True):
            title = title.replace(pattern.lower(), ' ')
        
        # nettoyage des caractères speciaux indesirables
        for symbol in self._get_config('general', 'symbols_to_exclude'):
            title = title.replace(symbol, ' ')
        return title

    def guess_mask_length(self):
        """ propose une longueur de masque pour le nom du fichier """
    
        t = self.file.split(self._get_config('general', 'film_name_separator'))
        string = self._clean_file_name(t[0])
        self.mask_length = len(string)
        return self.mask_length

    pass # end of class
    
